package com.web.music.impl;

import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import org.apache.commons.digester.Digester;

import com.web.music.common.MusicException;
import com.web.music.model.Person;
import com.web.music.xml.PeopleHolder;
import com.web.music.xml.XmlSchemaConst;

/**
 * This implementation uses Apache Digester (XML -> Java mapping approach).
 * http://commons.apache.org/digester/
 * 
 * Validation against XML Schema is not implemented.
 */
public class DigesterXmlParser extends BaseXmlParser {

	public Map<String, Person> extractPeopleInfo(File xmlFile) {
		System.out.println("[DigesterXmlParser] Starting to extract people info from File");
		Digester digester = initDigester();	
		PeopleHolder peopleHolder = null;
		try {
			peopleHolder = (PeopleHolder)digester.parse(xmlFile);
		} 
		catch (Exception e) {
			throw new MusicException(e);
		}
		Map<String, Person> map = convertHolderToMap(peopleHolder);
		System.out.println("[DigesterXmlParser] People info successfully extracted. In total [" + map.size() + "] items extracted");
		return map;
	}

	public Map<String, Person> extractPeopleInfo(InputStream input) {
		System.out.println("[DigesterXmlParser] Starting to extract people info from InpuitStream");
		Digester digester = initDigester();
		PeopleHolder peopleHolder = null;
		try {
			peopleHolder = (PeopleHolder)digester.parse(input);
		} 
		catch (Exception e) {
			throw new MusicException(e);
		}
		Map<String, Person> map = convertHolderToMap(peopleHolder);
		System.out.println("[DigesterXmlParser] People info successfully extracted. In total [" + map.size() + "] items extracted");
		return map;
	}
	
	private Digester initDigester()
	{
		Digester digester = new Digester();
		digester.setValidating(false);
		
		final String PEOPLE_PERSON = XmlSchemaConst.Entities.PEOPLE + "/" + XmlSchemaConst.Entities.PERSON;		// people/person
		
		digester.addObjectCreate(XmlSchemaConst.Entities.PEOPLE, PeopleHolder.class );					// people
		digester.addObjectCreate(PEOPLE_PERSON, Person.class );											// people/person
		digester.addSetProperties(PEOPLE_PERSON, XmlSchemaConst.Person.ID, "idString" );				// people/person/ "id"
		digester.addBeanPropertySetter(PEOPLE_PERSON + "/" + XmlSchemaConst.Person.NAME, "name" );		// people/person/name
		digester.addBeanPropertySetter(PEOPLE_PERSON + "/" + XmlSchemaConst.Person.SURNAME, "surname" );// people/person/surname
		digester.addSetNext(PEOPLE_PERSON + "/" + XmlSchemaConst.Person.NAME, "addPerson" );			// people/person
		
		return digester;
	}
	
	private Map<String, Person> convertHolderToMap(PeopleHolder peopleHolder){
		Vector<Person> people = peopleHolder.getPeople();
		Map<String,Person> map = new HashMap<String,Person>();
		for (Person p: people){
			p.setId(extractIdValue(p.getIdString(), XmlSchemaConst.IdPrefixes.PERSON_ID_PREFIX));
			map.put(p.getIdString(), p);
		}
		return map;
	}
	
}
